package hong.jun.pet_home.service.user.impl;

import com.alibaba.fastjson.JSONObject;
import hong.jun.basic.base.service.impl.BaseServiceImpl;
import hong.jun.basic.util.*;
import hong.jun.pet_home.domain.user.User;
import hong.jun.pet_home.domain.user.WXUser;
import hong.jun.pet_home.domain.util.SmsConstants;
import hong.jun.pet_home.domain.ato.Userato;
import hong.jun.pet_home.mapper.UserMapper;
import hong.jun.pet_home.mapper.WXUserMapper;
import hong.jun.pet_home.service.user.IWXUserService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class WXUserServiceImpl extends BaseServiceImpl<WXUser> implements IWXUserService {
    @Autowired
    private WXUserMapper wxUserMapper;
    @Autowired
    private UserMapper userMapper;

    /**
     * 微信扫码登录
     */
    @Override
    public AjaxResult wxLogin(Map<String, String> params, HttpServletResponse response) {
        String code = params.get("code");
        //替换请求头中的  应用唯一标识APPID 常量  应用密钥 ECRET常量   用户扫码获取的 CODE前台传来的
        String url = SmsConstants.GET_OPENID_URL.replace("APPID", SmsConstants.APPID)
                .replace("SECRET", SmsConstants.SECURITY)
                .replace("CODE", code);
        ///通过 code 获取 access_token ,openid,refresh_token.... 并转为json
        JSONObject jsonObject = JSONObject.parseObject(HttpClientUtils.httpGet(url));
        String accessToken = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");
        if (openid != null) {//拿到openid
            WXUser wxUser = wxUserMapper.getbyopenid(openid);
            if (wxUser != null) {//拿到绑定的user
                User user = wxUser.getWX_user();
                if (user.getState() == 1) {//用户状态正常
                    //随机数作为uToken
                    String uToken = UUID.randomUUID().toString();
                    //存到redis里
                    RedisUtils.INSTANCE.set(uToken, JSONObject.toJSONString(user), 30 * 60);
                    //返回对象为token和当前登录用户
                    Map<String, Object> resultObj = new HashMap<>();
                    resultObj.put("uToken", uToken);
                    resultObj.put("user", JSONObject.toJSONString(user));
                    return AjaxResult.me().setResultObj(resultObj);
                }//绑定的用户被禁用
                else return AjaxResult.me().setSuccess(false).setMessage("用户状态异常");
            } else {//没有拿到绑定用户user 跳转到绑定页面
                String binderUrl = params.get("binderUrl");//绑定页面
                binderUrl = binderUrl + "?access_token=" + accessToken + "&openId=" + openid;
                //返回绑定页面的url 和 access_token 及 openid
                return AjaxResult.me().setSuccess(false).setMessage("binder").setResultObj(binderUrl);
            }
        }//没有拿到 openid
        else return AjaxResult.me().setSuccess(false).setMessage("微信请求失败");
    }

    /**
     * 微信绑定用户
     */
    @Override
    public AjaxResult wxbinder(Map<String, String> params, HttpServletResponse response) {
        String username = params.get("username");
        String password = params.get("password");
        String accessToken = params.get("accessToken");
        String openId = params.get("openId");
        //替换请求头中的 调用凭证access_token  普通用户的标识，对当前开发者帐号唯一openid
        String url = SmsConstants.GET_WXUSER_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
        //发请求获取微信用户信息
        String httpGet = HttpClientUtils.httpGet(url);
        WXUser wxUser1 = jsonStr2WxUsxer(httpGet);
        if (wxUser1 != null) {//得到了用户信息
            //查询数据库有没有该username
            Userato userato = userMapper.wxloadById(username);
            //System.out.println(userato);
            if (userato != null) {//已有该用户
                System.out.println("已有该用户");
                if (userato.getWid() != null) {//该用户已被绑定
                    System.out.println("已有该用户且已被微信绑定");
                    return AjaxResult.me().setSuccess(false).setMessage("该用户名已存在并被绑定");
                } else {//有该用户 且没有被绑定
                    String md5password = MD5Utils.encrypByMd5(password + userato.getSalt());
                    //密码比对成功
                    if (md5password.equals(userato.getPassword())) {
                        System.out.println("密码比对成功");
                        User user = new User();
                        user.setId(userato.getId());
                        user.setUsername(userato.getUsername());
                        user.setAge(userato.getAge());
                        wxUser1.setWX_user(user);
                        //储存t_wxuser
                        wxUserMapper.save(wxUser1);
                        //随机数作为uToken
                        String uToken = UUID.randomUUID().toString();
                        //存到redis里
                        RedisUtils.INSTANCE.set(uToken, JSONObject.toJSONString(user), 30 * 60);
                        //返回对象为token和当前登录用户
                        Map<String, Object> resultObj = new HashMap<>();
                        resultObj.put("uToken", uToken);
                        resultObj.put("user", user);
                        return AjaxResult.me().setResultObj(resultObj);
                    } else {//密码比对失败
                        System.out.println("密码比对失败");
                        return AjaxResult.me().setSuccess(false).setMessage("密码错误");
                    }
                }
            } else {//没有该用户 新增用户并绑定
                //数据处理
                User user = new User();
                String salt = StrUtils.getComplexRandomString(32);//生成随机数作为盐
                String md5password = MD5Utils.encrypByMd5(password + salt);//给密码加盐
                user.setUsername(username);
                user.setSalt(salt);
                user.setPassword(md5password);
                user.setState(1);//状态为正常
                user.setCreatetime(new Date());
                //储存t_user
                userMapper.save(user);//储存成功后会改变user的id
                wxUser1.setWX_user(user);
                System.out.println(wxUser1);
                //储存t_wxuser
                wxUserMapper.save(wxUser1);
                //随机数作为uToken
                String uToken = UUID.randomUUID().toString();
                //存到redis里
                RedisUtils.INSTANCE.set(uToken, JSONObject.toJSONString(user), 30 * 60);
                //返回对象为token和当前登录用户
                Map<String, Object> resultObj = new HashMap<>();
                resultObj.put("uToken", uToken);
                resultObj.put("user", user);
                return AjaxResult.me().setResultObj(resultObj);
            }
        }
        return AjaxResult.me().setSuccess(false).setMessage("获取微信用户信息失败");
    }

    /**
     * 对微信用户数据处理方法
     */
    @SneakyThrows
    private WXUser jsonStr2WxUsxer(String jsonStr) {
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        WXUser wxUser = new WXUser();
        wxUser.setOpenid(jsonObject.getString("openid"));
        wxUser.setNickname(jsonObject.getString("nickname"));
        String nickname = jsonObject.getString("nickname");
        nickname = new String(nickname.getBytes("ISO-8859-1"), "UTF-8");
        wxUser.setNickname(nickname);
        wxUser.setSex(jsonObject.getInteger("sex"));
        wxUser.setAddress(null);
        wxUser.setHeadimgurl(jsonObject.getString("headimgurl"));
        wxUser.setUnionid(jsonObject.getString("unionid"));
        return wxUser;
    }
}
